﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;

namespace FlickrSample.SL.Infrastructure.Repo.Download.Online
{
    public class WebDownloader : IWebDownloader
    {

        private bool isDownloading;

        public event EventHandler<UnhandledExceptionEventArgs> DownloadError;

        class DownloadQueueObject
        {
            public Action<Stream> Callback { get; set; }
            public Uri Uri { get; set; }
        }

        private Queue<DownloadQueueObject> downloadQueue = new Queue<DownloadQueueObject>();

        public void DownloadData(Uri uri, Action<Stream> callback)
        {

           // var queueObject = downloadQueue.Dequeue();

            var client = getClient();

            Debug.WriteLine("Downloading: " + uri.AbsoluteUri);

            client.OpenReadCompleted += (s, e) =>
            {
                if (e.Error != null)
                {
                    //handle web error
                    Debug.WriteLine("Could not download: " + uri.AbsoluteUri);
                    if (DownloadError != null)
                    {
                        DownloadError(this, new UnhandledExceptionEventArgs(e.Error, false));
                    }
                    callback(null);
                }
                else
                {
                    Debug.WriteLine("Finished Downloading: " + uri.AbsoluteUri);
                    callback(e.Result);
                }
                processQueue();
            };

            client.OpenReadAsync(uri);
            
            //downloadQueue.Enqueue(new DownloadQueueObject() {Callback = callback, Uri = uri});
            
            //if (!isDownloading)
            //{
            //    processQueue();
            //}
        }
        
        void processQueue()
        {
            isDownloading = true;
            
            if (downloadQueue.Count > 0)
            {
                var queueObject = downloadQueue.Dequeue();

                var client = getClient();

                Debug.WriteLine("Downloading: " + queueObject.Uri.AbsoluteUri);

                client.OpenReadCompleted += (s, e) =>
                {
                    if (e.Error != null)
                    {
                        //handle web error
                        Debug.WriteLine("Could not download: " + queueObject.Uri.AbsoluteUri);
                        if (DownloadError != null)
                        {
                            DownloadError(this, new UnhandledExceptionEventArgs(e.Error, false));
                        }
                        queueObject.Callback(null);
                    }
                    else
                    {
                        Debug.WriteLine("Finished Downloading: " + queueObject.Uri.AbsoluteUri);
                        queueObject.Callback(e.Result);
                    }
                    processQueue();
                };

                client.OpenReadAsync(queueObject.Uri);
            }
            else
            {
                isDownloading = false;
            }
        }

        WebClient getClient()
        {
            return new WebClient();
        }
    }
}
